#include "cubeshader.h"
#include <math.h>
#include <QDir>

CubeShader::CubeShader(QObject *parent)
    :BaseShader(parent)
{
    m_file_vert = ":/chest.vert";
    m_file_frag = ":/chest.frag";

    ourModel = new MyModel(QDir::currentPath() + "/../models/untitled.obj");
}

void CubeShader::initializeGL()
{
    BaseShader::initializeGL();

    aPos = m_program->attributeLocation("aPos");
    aNormal = m_program->attributeLocation("aNormal");
    aTexCoords = m_program->attributeLocation("aTexCoords");

    //给每一个网格分配数据
    qInfo()<<"给每一个网格分配数据"<<ourModel->meshes.size();
    for(int i = 0; i < ourModel->meshes.size(); i++)
    {
        GLuint vao;
        GLuint vbo;
        GLuint ebo;

        glGenVertexArrays(1, &vao);
        vaos.push_back(vao);
        glBindVertexArray(vao);

        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * ourModel->meshes[i].vertices.size(), &ourModel->meshes[i].vertices[0], GL_STATIC_DRAW);

        glGenBuffers(1, &ebo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * ourModel->meshes[i].indices.size(), &ourModel->meshes[i].indices[0], GL_STATIC_DRAW);

        glEnableVertexAttribArray(aPos);
        glEnableVertexAttribArray(aNormal);
        glEnableVertexAttribArray(aTexCoords);

        glVertexAttribPointer(aPos, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
        glVertexAttribPointer(aNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, Normal)));
        glVertexAttribPointer(aTexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, TexCoords)));

        unsigned int diffuseNr = 1;
        unsigned int specularNr = 1;
        unsigned int normalNr = 1;
        unsigned int heightNr = 1;
        //生成纹理
        //        qInfo()<<"生成纹理"<<ourModel->meshes[i].textures.size();
        for(int j = 0; j < ourModel->meshes[i].textures.size(); j++)
        {
            QString name = ourModel->meshes[i].textures[j].type;
            QString path = QDir::currentPath() + "/../models/" + ourModel->meshes[i].textures[j].path;

            QString number;
            unsigned int index = 0;
            if(name == "texture_diffuse")
            { number = QString::number(diffuseNr++); index = 0; }
            else if(name == "texture_specular")
            { number = QString::number(specularNr++); index = 1; } // transfer unsigned int to string
            else if(name == "texture_normal")
            { number = QString::number(normalNr++); index = 2; } // transfer unsigned int to string
            else if(name == "texture_height")
            { number = QString::number(heightNr++); index = 3; } // transfer unsigned int to string

            if(path == "" || path.trimmed().isEmpty()) continue;
            bool skip = false;
            for(int k = 0; k < texturePathBacks.size(); k++)
            {
                if(texturePathBacks[k] == ourModel->meshes[i].textures[j].path)
                {
                    skip = true; break;
                }
            }
            if(skip) continue;

            texturePathBacks.push_back(ourModel->meshes[i].textures[j].path);
            //            qInfo()<<"---"<<texturePathBacks.size();

            QOpenGLTexture* texture = new QOpenGLTexture(QImage(path));
            texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
            texture->setMagnificationFilter(QOpenGLTexture::Linear);

            SQOpenGLTexture sq;
            sq.meshId = i;  // 为每个mesh指定texture
            sq.id = index;
            sq.t = texture;

            myTextures.push_back(sq);
        }

        glBindVertexArray(0);
    }

//    for(int a = 0; a < texturePathBacks.size(); a++)
//    {
//        qInfo()<<"a " << a << texturePathBacks[a];
//    }
}

void CubeShader::paintGL()
{
    glClearColor(0.05f, 0.05f, 0.05f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_program->bind();

    m_program->setUniformValue("projection", projection);
    m_program->setUniformValue("view", view);

    //    ourModel->Draw(m_program);
    // 7个mesh
    //    qInfo()<<"---"<<ourModel->meshes.size();
    for(int i = 0; i < ourModel->meshes.size(); i++)
    {
        // 6=body, 4=hand, 5=head
        glBindVertexArray(vaos[i]);

        QMatrix4x4 model;

//        model.rotate(180.0f, QVector3D(0.0f, 1.0f, 0.0f));
        model.scale(0.02f);
//        model.translate(30.0f, 0.0f, 0.0);
        m_program->setUniformValue("model", model);

        for(int j = 0; j < myTextures.size(); j++)
        {
            if(myTextures[j].meshId == i)
                myTextures[j].t->bind(myTextures[j].id);
        }
        glDrawElements(GL_TRIANGLES, ourModel->meshes[i].indices.size(), GL_UNSIGNED_INT, 0);

        for(int j = 0; j < myTextures.size(); j++)
        {
            if(myTextures[j].meshId == i)
                myTextures[j].t->release();
        }
    }

    m_program->release();
}
